16. 설계를 방해하는 개발 프로세스와의 싸움
📌 Contents
📌 커뮤니케이션
- 팀원 간 의사소통에 문제가 있으면, 버그가 많아지는 경향이 있음
- 커뮤니케이션 문제 해결과 관련된
콘웨이 법칙(Conway's law)
은 '시스템의 구조는 그것을 설계하는 조직의 구조를 닮아 간다'라는 법칙 - 만들어야 하는 시스템의 구조와 조직 구조에 차이가 있다면, 시스템 구조를 제대로 잡기 어려워짐
- 그래서 최근에 '소프트웨어의 구조를 먼저 설계하고, 이후 소프트웨어의 구조에 맞게 편성한다'는 접근 방법인
역콘웨이 법칙(inverse Conway's law)
이라는 것이 등장함 - 하지만 역콘웨이 법칙을 내세우며 팀을 구성하더라도, 팀 내부의 관계에 문제가 있다면, 본질적인 문제가 해결되지 않음
- 팀원 간 관계 개선에는 심리적 안정성이 중요함
- 커뮤니케이션에 문제가 있을 때는 일단 심리적 안정성 향상에 힘쓰는 것이 좋음
📌 설계
- 설계는 굉장히 중요한 개발 프로세스임
- 설계가 제대로 이루어지지 못하게 하거나, 설계한 것이 제대로 동작하지 않게 하는 다양한 함정이 있음
'빨리 끝내고 싶다'는 심리가 품질 저하의 함정
- 설계 품질을 신경 쓰지 않고, 어떻게든 작동하는 코드를 빠르게 작성하는 프로그래머는 초반에 빨리 구현할 수 있음
- 하지만 시간이 지날수록 구현 속도가 느려짐
- 조악한 구현 때문에 코드 수정이 다른 곳에 영향을 미치기 때문임
- 이들이 완성했다고 이야기해도, 이후로 게속해서 버그 수정을 하게 됨
나쁜 코드를 작성하는 것이 좋은 코드를 작성하는 것보다 오래 걸린다
- 테스트 주도 개발(TDD)을 사용할 경우와 안할 경우 어느쪽이 더 빠를까 비교 실험이 있음
- TDD는 프로덕션 코드 이외에도 테스트 코드를 추가로 구현해야 하므로, 언뜻 더 느릴 것처럼 보임
- 하지만 실제 실험에서는 TDD를 사용하는 편이 전체적으로 보았을 때 더 빠르다는 결론이 나옴
클래스 설계와 구현 피드백 사이클 돌리기
- 사양을 변경할 때는 최소한 메모로라도 클래스 다이어그램을 그려라
- 이를 기반으로 팀과 간단하게 리뷰하고, 문제가 없어 보이면 구현해라
- 구현하다 보면 예상하지 못했던 요소들을 발견하게 되는데, 이때마다 클래스 다이어그램에 반영해라
- 설계와 구현 피드백 사이클을 돌리다 보면, 설계 품질이 향상될 것이다
한 번에 완벽하게 설계하려고 들지 말고, 사이클을 돌리며 완성하기
- 처음부터 너무 완벽하게 설계하려고 하면, 구현이 설계와 달라질 때 정신적인 충격을 많이 받음
- 단 한 번의 설계로 완벽한 구조를 만들어 낼 수 없음
- 설계 품질은 설계와 구현 피드백 사이클을 계속해서 돌리면, 조금씩 향상되는 것임
'성능이 떨어질 수 있으니 클래스를 작게 나누지 말자'는 맞는 말일까?
- 클래스가 많아지면 비용이 발생하는 것은 맞지만, 대부분의 상황에는 무시할 수 있는 정도임
- 병목이 어디인지 모른 채 성능이 빠른 코드를 작성하려고만 하는 것은
너무 빠른 최적화(premature optimization)
라고 하는 안티 패턴임 - 실제로는 성능과 관련 없는 부분인데 '이렇게 하면 빠를 것이다'라고 생각하고 작성하는 코드는 대부분 변경 용이성이 낮음
설계 규칙을 다수결로 결정하면 코드 품질은 떨어진다
- 다수결 또는 만장일치로 코드와 설계를 결정하려고 하면, 아무래도 수준이 낮은 쪽에 맞춰서 하향평준화되기 쉬움
- 설계 기술이 미숙한 팀원이 제한된 규칙의 좋고 나쁨을 제대로 판단하기는 어려움
- 결국 조악한 규칙이 채택될 수도 있고, 규칙 자체가 만들어지지 않을 수 도 있음
설계 규칙을 정할 떄 중요한 점
- 설계 역량이 뛰어난 팀원이 중심이 되어 규칙을 만드는 것이 좋음
- 설계 규칙에는 이유와 의도를 함께 적는 것이 좋음
- 팀의 설계 역량이 성숙하지 않으면, 어느 정도 아는 팀원이 설계 리뷰와 코드 리뷰를 하도록 하는 것이 좋음
- 리뷰만으로 어렵다면, 스터디를 진행해 보는 것도 좋음
📌 구현
- 관점과 접근 방법을 바꾸면, 코드를 구현하는 방법이 달라질 수 있음
깨진 유리창 이론과 보이스카우트 규칙
- 조악하고 복잡하고 질서 없는 코드가 방치되면, 소프트웨어 전체가 점점 더 무질서해짐
- 코드를 변경할 때, 자신이 변경하기 전보다 더 깨끗한 상태로 만들어 커밋하다보면, 코드의 전체적인 질서가 점점 더 좋아질 것임
- 나쁜 구조가 눈에 띄면, 조금씩이라도 좋으니 개선하는 습관을 기르자
- 미국의 보이스카우트에는 '캠핑장을 자신이 왔을 때보다 더 깨끗하게 치우고 가기'라는 규칙이 있음
기존의 코드를 믿지 말고, 냉정하게 파악하기
- 레거시 코드를 박멸하려면, 기존의 코드를 맹신하지 않는 마음가짐이 중요함
- 이상적인 설계를 처음부터 다시 생각해 보는 것을 정체를 파악하는 행위라고 함
- 정체를 파악할 때, 넘어야하는 장애물이 몇 가지 있음
- 처음 제시한 수치와 정보가 기준이 되어, 이후의 판단을 왜곡하는 인지 편향인 앵커링 효과라고 하는 심리 작용
- 이름이 없거나, 이름을 모르는 것은 인지하기 어렵다는 것
- 이러한 두 장애물을 극복하면, 냉정하게 정체를 파악하고, 클래스와 메서드에 정체를 표현하는 이름을 붙일 수 잇을 것임
- 이 외에도 코딩 규칙을 사용하거나, 명명 규칙을 잘 지키는 등의 방법이 있음
📌 리뷰
- 리뷰 시 주의 사항 정리
코드 리뷰 구조화하기
- 풀 리퀘스트한 코드는 '코드의 히스토리와 경위를 알고 있는 사람' 또는 '설계를 자세하게 알고 있는 사람'이 리뷰하는 것이 좋음
- 풀 리퀘스스 작성 시 템플릿 텍스트에는 리뷰 관점을 명시하는 것이 좋음
- 보이스카우트 규칙 확인 항목, 설계 규칙과 관련된 링크 등을 포함하는 것도 좋음
코드를 설계 시점에 리뷰하기
- 많은 사람이 코드 리뷰를 '로직이 기능 요건을 만족하는지, 결함이 존재하는지, 코딩 스타일을 지키고 있는지 리뷰하는 것'이라고 생각함
- 하지만 이보다는 설계의 타당성을 중심으로 리뷰해야 함
존중과 예의
- 코드 리뷰에서 가장 중요한 것은 존중과 예의임
- 기술적 올바름과 유용성보다도 함께 일하는 동료를 존중하는 것이 먼저임
- 존중과 예의를 갖추고 지적하는 것이 코드 품질을 높이는 가장 빠른 길임
정기적으로 개선 작업 진행하기
- 구현 또는 코드 리뷰 중간에 좋지 않은 코드를 발견했는데, 스케줄 문제로 대처하지 못하는 경우가 있을 수 있음
- 이때 일반적으로 '나중에 고치자'하고 넘어가곤 함
- 하지만 이렇게 넘어간 결함은 새로운 업무가 계속해서 할당되기 때문에, 대부분 특별한 대책 없이 방치됨
- 좋지 않은 코드에 대처하는 일은 작업 관리 도구에 개선 작업으로 추가해 두고, 정기적으로 이러한 작업을 모아 개선 작업을 진행해서, 확실하게 대처할 수 있게 만드는 것이 좋음
📌 팀의 설계 능력 높이기
- 지금까지 다룬 개발 프로세서는 설계 역량이 뛰어난 팀원이 어느정도 있을 때의 이야기임
그렇지 않을 때 어떻게 하는 것이 좋을까?
영향력을 갖는 규모까지 동료 구하기
- 설계 뿐만 아니라 일의 방식을 상향식으로 개선하려면, 주위의 협력이 반드시 필요함
- 서로 협력해야 일하는 방식을 바꿀 만큼 큰 영향력이 생기기 떄문임
- 천리길도 한 걸음부터
- 사람은 한 번에 대량의 정보를 받아들일 수 없으며, 큰 변화에 대한 불안과 저항을 느낌
- 매일매일 조금씩 설계 지식을 공유하도록 하자
- 백문이 불여일견
- 동료와 설계 지식을 어느 정도 공유 했다면, 함께 클래스를 설계하고 구현한 뒤 리뷰해 보자
- 가상의 사양과 코드를 사용하기 보단, 프로덕션 코드를 사용해보자
- 복잡함과 무질서함은 실제 프로덕션 코드를 따라갈 수 없기 때문임
- 팔로우업 스터디 진행하기
- 인풋보다 아웃풋이 학습 효과가 높음
- 리더와 매니저에게 설계의 중요성과 비용 대비 효과 설명하기
- 매니저에게 비용 대비 효과를 중심으로 이야기하자
- 매니저는 팀에 할당된 예산을 투자해 이익을 극대화해야 하는 책임이 있기 때문임
- 매니저에게 비용 대비 효과를 중심으로 이야기하자
- 설계 책임자 세우기
- 설계 책임자가 추진해야 하는 내용
- 설계 품질과 관련된 규칙이나 개발 프로세스 수립
- 규칙을 반복적으로 알리고 교육
- 리더와 매니저에게 효과 공유
- 품질 시각화
- 설계 품질 유지
- 팀에 적당한 인물이 없다면 직접 해보자
- 설계 책임자가 추진해야 하는 내용